package com.kancy.vip.pattern.template;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author kancy
 * @date 2019/3/17 17:13
 */
public abstract class JdbcTemplate {

	private DataSource dataSource;

	public <T> List<T> executeQuery(String sql, Object[] params, RowHander<T> rowHander) throws SQLException {

		// 1.获取连接
		Connection connetion = getConnetion();

		// 2.创建statement
		PreparedStatement ps = connetion.prepareStatement(sql);

		// 3.设置参数i
		setParams(params, ps);

		// 4.执行语句
		ResultSet rs = ps.executeQuery();

		// 5.处理结果集
		List<T> result = processResultSet(rs,rowHander);

		// 6.关闭结果集
		closeRs(rs);

		// 7.关闭statement
		closeStatement(ps);

		// 8.关闭连接
		closeConn(connetion);

		return result;

	}

	protected void closeConn(Connection connetion) throws SQLException {
		connetion.close();
	}

	private void closeStatement(PreparedStatement ps) throws SQLException {
		ps.close();
	}

	private void closeRs(ResultSet rs) throws SQLException {
		rs.close();
	}

	private <T> List<T> processResultSet(ResultSet rs, RowHander<T> rowHander) throws SQLException {
		int rowNum = 1;
		List<T> list = new ArrayList<T>();
		while(rs.next()){
			T t = rowHander.processRow(rs, rowNum++);
			list.add(t);
		}
		return list;
	}

	private void setParams(Object[] params, PreparedStatement ps) throws SQLException {
		if(params!=null && params.length>0){
			int size = params.length;
			for (int i = 0; i < size; i++) {
				ps.setObject((i+1), params[i]);
			}
		}
	}

	private Connection getConnetion() throws SQLException {
		return dataSource.getConnection();
	}
}
